package net.tomblog.app.swingheil.activity;

import net.tomblog.app.swingheil.R;
import net.tomblog.app.swingheil.model.Article;
import net.tomblog.app.swingheil.model.ArticleSearch;
import net.tomblog.app.swingheil.parser.ArticleParser;
import net.tomblog.app.swingheil.parser.DaumArticleParser;
import net.tomblog.app.swingheil.parser.GetArticleListTask;
import net.tomblog.app.swingheil.parser.NaverArticleParser;
import net.tomblog.app.swingheil.parser.ArticleParser.ArticleListener;
import net.tomblog.app.swingheil.provider.ArticleProvider;
import net.tomblog.app.swingheil.util.DefaultPreference;
import net.tomblog.app.swingheil.util.L;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.SimpleCursorAdapter.ViewBinder;

/**
 * 게시판 글 리스트를 표시하는 Activity
 * 
 * @author hyunung.park (parkbear01@gmail.com)
 * 
 */
public class ArticleListActivity extends BaseActivity {
 
	private static final String TAG = "ArticleListActivity";
	
	public static final int RESET_CURRENT_PAGE = 21;
	
	private ListView mArticleListView;
	private Button mNoArticle;
	private LayoutInflater mInflater;
	private View mMoreView;
	private View mMoreText;
	private View mMoreProgress;
	private Activity mActivity;
	private AsyncTask<ArticleSearch, Integer, Boolean> mAsyncTask;
	
	private ArticleParser mArticleParser;
	private SimpleCursorAdapter mArticleListAdapter;
	private DefaultPreference mPref;
	
	private String mCafeId;
	private String mBoardId;
	// 현재 게시판의 페이지 번호
	private int mCurrentSearchPage = 1;
	// 더보기가 클릭되었는지 여부(중복 클릭을 방지)
	private boolean mIsMoreClicked;
    
	private static String[] mSelectionArgs = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		L.d(TAG, " >>> called onCreate()");
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.article_list_activity);
  
		Intent intent = getIntent();
		mCafeId = intent.getStringExtra(ArticleParser.INTENT_CAFE_ID);
		mBoardId = intent.getStringExtra(ArticleParser.INTENT_BOARD_ID);
		mSelectionArgs = new String[] { mCafeId, mBoardId };
    	
		inflateView();

		initObject();
		
		super.onCreate(savedInstanceState);
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		L.d(TAG, " >>> called onPause()");
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		L.d(TAG, " >>> called onDestroy()");
		mPref.storePreference(mCafeId + mBoardId, String.valueOf(mCurrentSearchPage));
		L.e(TAG, "saved mCurrentSearchPage : " + mCurrentSearchPage);
	}
 
	@Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_LOADING: {
            	ProgressDialog dialog = new ProgressDialog(this);
        		dialog.setMessage("Please wait while loading...");
        		dialog.setIndeterminate(true);
        		dialog.setCancelable(true);
        		dialog.setOnCancelListener(new OnCancelListener() {
					@Override
					public void onCancel(DialogInterface dialog) {
						L.d(TAG, " >>> called ProgressDialog.onCancel()");
						mAsyncTask.cancel(true);
					}
				});
        		return dialog;
            }
            case DIALOG_CONNECT_NETWORK: {
            	 return new AlertDialog.Builder(mActivity)
                 .setIcon(R.drawable.alert_dialog_icon)
                 .setTitle(R.string.alert_dialog_title_connect_network)  
                 .setMessage(R.string.alert_dialog_message_connect_network)  
                 .setPositiveButton(R.string.alert_dialog_connect, new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int whichButton) {
                    	 Intent intent = new Intent();
                    	 intent.setClassName("com.android.settings", "com.android.settings.WirelessSettings");
                    	 mActivity.startActivity(intent);
                     }
                 })
                 .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int whichButton) {
                     }
                 })
                 .create();
            }
        }
        return null;
    }
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.article_list_menu, menu);
		
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.set_db:
			Intent intent = new Intent(ArticleListActivity.this, ManageDBActivity.class);
			intent.putExtra(ArticleParser.INTENT_CAFE_ID, mCafeId);
			intent.putExtra(ArticleParser.INTENT_BOARD_ID, mBoardId);
 			startActivityForResult(intent, ManageDBActivity.MANAGE_DB);
			return true;
		case R.id.delete:
			getContentResolver().delete(Article.CONTENT_URI, Article.SELECTION, mSelectionArgs);
			mArticleListView.setVisibility(View.GONE);
    		mNoArticle.setVisibility(View.VISIBLE);
    		mCurrentSearchPage = 1;
			mPref.storePreference(mCafeId + mBoardId, null);
			return true;
		case R.id.refresh:
			if(isNetworkAvailable()) {
				int count = mArticleListAdapter.getCursor().getCount();
				boolean needProgressDialog = (count == 0) ? true : false;
				setMoreView(true);
				ArticleSearch articleSearch = new ArticleSearch(mCafeId, mBoardId, 1); 
				articleSearch.setIncreasingSearchPage(false);
				mAsyncTask = new GetArticleListTask(mArticleParser, mArticleListener, mActivity, needProgressDialog).execute(articleSearch);
			}else {
				showDialog(DIALOG_CONNECT_NETWORK);
			}
			return true;
		default:
			break;
		}

		return false;
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case ManageDBActivity.MANAGE_DB:
			if(resultCode == RESET_CURRENT_PAGE) {
				L.d(TAG, " >>> called onActivityResult() and requestCode is RESET_CURRENT_PAGE");
				mCurrentSearchPage = 1;
				checkListEmpty();
			}
			break;

		default:
			break;
		}
	}
	
	private void inflateView() {
		L.d(TAG, " >>> called inflateView()");
		
		mInflater = LayoutInflater.from(this);
		
		mRootView  = (ViewGroup)findViewById(R.id.root);
		mArticleListView = (ListView)findViewById(R.id.article_list);
		mNoArticle = (Button)findViewById(R.id.no_article);
		mMoreView = mInflater.inflate(R.layout.list_item_more, mArticleListView, false);
		mMoreText = mMoreView.findViewById(R.id.more_text);
		mMoreProgress = mMoreView.findViewById(R.id.more_progress);
	}

    private void initObject() {
    	L.d(TAG, " >>> called initObject()");
    	
    	mNoArticle.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
    			if(mIsMoreClicked == false) {
    				L.e(TAG, "mNoArticle is clicked");
    				if(isNetworkAvailable()) {
    					setMoreView(true);
    					mCurrentSearchPage = 1;
    					ArticleSearch articleSearch = new ArticleSearch(mCafeId, mBoardId, mCurrentSearchPage);
    					mAsyncTask = new GetArticleListTask(mArticleParser, mArticleListener, mActivity, true).execute(articleSearch);
    				}else {
    					showDialog(DIALOG_CONNECT_NETWORK);
    				}
    			}
			}
		});
    	mActivity = ArticleListActivity.this;
    	mArticleListView.addFooterView(mMoreView);
    	mMoreView.setOnClickListener(new OnClickListener() {
    		@Override
    		public void onClick(View v) {
    			if(mIsMoreClicked == false) {
    				L.e(TAG, "mMoreView is clicked");
    				if(isNetworkAvailable()) {
    					setMoreView(true);
    					ArticleSearch articleSearch = new ArticleSearch(mCafeId, mBoardId, mCurrentSearchPage);
    					mAsyncTask = new GetArticleListTask(mArticleParser, mArticleListener, mActivity, false).execute(articleSearch);
    				}else {
    					showDialog(DIALOG_CONNECT_NETWORK);
    				}
    			}
    		}
    	});
    	mMoreView.setVisibility(View.GONE);
    	
    	Cursor cursor = getContentResolver().query(Article.CONTENT_URI, Article.PROJECTION, Article.SELECTION, mSelectionArgs, null);
    	String[] from = {
    			Article.ARTICLE_TITLE, Article.NICKNAME
    	};
    	int[] to = {
    			R.id.text1, R.id.text2
    	};
    	mArticleListAdapter = new SimpleCursorAdapter(ArticleListActivity.this, R.layout.list_item_article, cursor, from, to);
    	mArticleListAdapter.setViewBinder(new ViewBinder() {
			@Override
			public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
//				L.w(TAG, " >>> called setViewValue()");
				 switch (view.getId()) {
			        case R.id.text1:
			            String title = cursor.getString(cursor.getColumnIndex(Article.ARTICLE_TITLE));
			            ((TextView)view).setText(Html.fromHtml(title).toString());
			            return true;
			        default:
			            return false;
			        }
			}
		});
    	mArticleListView.setAdapter(mArticleListAdapter);
    	mArticleListView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				L.d(TAG, "position : " + position + " id : " + id);
				
				if(isNetworkAvailable()) {
					Cursor cursor = (Cursor)mArticleListAdapter.getItem(position);
					Article article = ArticleProvider.getArticleFromCursor(cursor);
					
					String url = mArticleParser.getArticleReadURL(article);
					
					Intent intent = new Intent(mActivity, ArticleViewActivity.class);
					intent.putExtra(ArticleViewActivity.PARAM_URL, url);
					startActivity(intent);
				}else {
					showDialog(DIALOG_CONNECT_NETWORK);
				}
			}
		});

    	mPref = new DefaultPreference(this);
    	String searchPage = mPref.getPreference(mCafeId + mBoardId);
    	L.e(TAG, "loaded searchPage : " + searchPage);
    	if(searchPage != null) {
    		mCurrentSearchPage = Integer.parseInt(searchPage);    	
    		L.d(TAG, "loaded mCurrentSearchPage : " + mCurrentSearchPage);
    	}
    	
    	int potalSiteId = ArticleParser.getPotalSiteId(mCafeId);
    	if(potalSiteId == ArticleParser.NAVER) {
    		mArticleParser = new NaverArticleParser(); 
    	}else if(potalSiteId == ArticleParser.DAUM) {
    		mArticleParser = new DaumArticleParser();
    	}
    	
    	// DB에 데이터가 없을 때
    	if(cursor.moveToFirst() == false){
    		// 네트워크가 사용가능할 때, 리스트를 불러온다.
    		if(isNetworkAvailable()) {
    			ArticleSearch articleSearch = new ArticleSearch(mCafeId, mBoardId, mCurrentSearchPage);
    			mAsyncTask = new GetArticleListTask(mArticleParser, mArticleListener, mActivity, true).execute(articleSearch);
    		}else {
    			checkListEmpty();
    		}
    	}else {
    		mMoreView.setVisibility(View.VISIBLE);
    		setMoreView(false);
    	}
	}
    
    /**
     * 현재 로딩중인지의 상태를 표시
     * @param isLoading
     */
	private void setMoreView(boolean isLoading) {
		if(isLoading) {
			mIsMoreClicked = true;
			mActivity.setProgressBarIndeterminateVisibility(true);
			mMoreText.setVisibility(View.GONE);
			mMoreProgress.setVisibility(View.VISIBLE);
		}else {
			mIsMoreClicked = false;
            mActivity.setProgressBarIndeterminateVisibility(false);
            mMoreText.setVisibility(View.VISIBLE);
            mMoreProgress.setVisibility(View.GONE);
		}
	}
    
    private ArticleListener mArticleListener = new ArticleListener() {
		@Override
    	public void onComplete(boolean needToIncreasePaging) {
    		L.e(TAG, " >>> called onComplete()"); 
            
            // 처음 리스트 로딩 후 더보기 View 보여주기
            mMoreView.setVisibility(View.VISIBLE);
            
    		Cursor cursor = getContentResolver().query(Article.CONTENT_URI, Article.PROJECTION, Article.SELECTION, mSelectionArgs, null);
    		mArticleListAdapter.changeCursor(cursor);
    		
    		if(needToIncreasePaging) {
    			mCurrentSearchPage++;
    		}
    		
    		// 새로고침을 한후 이전에 남아있던 글들이 지워졌다면 Paging번호를 1로 초기화
    		if(cursor.getCount() < ArticleSearch.DEFAULT_SEARCH_PER_PAGE) {
    			mCurrentSearchPage = 1;
    		}else if(cursor.getCount() == ArticleSearch.DEFAULT_SEARCH_PER_PAGE){
    			mCurrentSearchPage = 2;
    		}
    		
            checkListEmpty();
            setMoreView(false);
    	}
    	@Override
    	public void onError(int errorCode, String msg) {
    		L.e(TAG, " >>> called onError()");
    		switch (errorCode) {
			case ERROR_NETWORK_PROBLEM:
				Toast.makeText(mActivity, R.string.toast_network_problem, Toast.LENGTH_SHORT).show();
				break;
			case ERROR_CANCELED:
				mArticleParser.setIsCanceled(false);
				Toast.makeText(mActivity, R.string.toast_canceled, Toast.LENGTH_SHORT).show();
				break;
			default:
				break;
			}

    		checkListEmpty();
            setMoreView(false);
    	}
    };

    public void checkListEmpty() {
    	int count = mArticleListAdapter.getCursor().getCount();
    	if(count == 0) {
    		mArticleListView.setVisibility(View.GONE);
    		mNoArticle.setVisibility(View.VISIBLE);
    	}else {
    		mMoreView.setVisibility(View.VISIBLE);
    		mArticleListView.setVisibility(View.VISIBLE);
    		mNoArticle.setVisibility(View.GONE);
    	}
    }
    
}